package com.lambkit.node;

import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import com.lambkit.core.Lambkit;
import com.lambkit.node.c2p.LambkitNodeC2p;
import com.lambkit.node.parent.LambkitNodeP2c;
import com.lambkit.node.s2p.LambkitNodeS2p;

import java.util.Map;


public class LambkitNodeManager {

	private static LambkitNodeManager manager;

	public static LambkitNodeManager me() {
		if(manager==null) {
			manager = Lambkit.get(LambkitNodeManager.class);
		}
		return manager;
	}
	
	private LambkitNode node = null;
	
	/**
	 * 父节点
	 */
	private LambkitParentNode parentNode;
	/**
	 * 兄弟（备份）节点，
	 */
	private LambkitSiblingNode siblingNode;
	/**
	 * 子节点
	 */
	private Map<String, LambkitChildNode> childNodes = MapUtil.newConcurrentHashMap();
	
	private LambkitNodeService service;
	
	public static final String route = "/lambkit/net/node";
	public static final String cacheName = "lambkit_node";
	public static final String nodekey = "our_node_info";

	public void initNode() {
		LambkitNode node = null;
		if(node==null) {
			node = Lambkit.getCache()!=null ? Lambkit.getCache().get(cacheName, nodekey) : null;
		}
		if(node==null || StrUtil.isBlank(node.getId())) {
			node = new LambkitNode();
			LambkitNodeConfig config = Lambkit.config(LambkitNodeConfig.class);
			String nodeId = getNodeId(config.getId());
			node.setId(nodeId);
			node.setApplicationName(config.getApplicationName());
			node.setType(config.getType());
			LambkitNodeUrlConfig urlConfig = Lambkit.config(LambkitNodeUrlConfig.class);
			NetUrl netUrl = new NetUrl();
			netUrl.setGroup(urlConfig.getGroup());
			netUrl.setDomain(urlConfig.getDomain());
			netUrl.setProtocal(urlConfig.getProtocal());
			//int port = urlConfig.getPort()==0 ? LambkitBeanManager.me().getPort() : urlConfig.getPort();
			int port = urlConfig.getPort();
			netUrl.setPort(port);
			node.setUrl(netUrl);
			if(Lambkit.getCache()!=null) {
				Lambkit.getCache().put(cacheName, nodekey, node);
			}
		}
		this.node = node;
	}

	public String getNodeId(String id) {
		String nodeId = id;
		if(StrUtil.isBlank(id)) {
			nodeId = Lambkit.getCache().get("LAMBKIT_NODE", "lambkit_node_id");
		} else {
			Lambkit.getCache().put("LAMBKIT_NODE", "lambkit_node_id", nodeId);
		}
		if(StrUtil.isBlank(nodeId)) {
			nodeId = IdUtil.randomUUID();
			Lambkit.getCache().put("LAMBKIT_NODE", "lambkit_node_id", nodeId);
		}
		return nodeId;
	}

	
	public LambkitChildNode addChildNode(LambkitNodeC2p node) {
		if(node!=null) {
			LambkitChildNode child = childNodes.get(node.getId());
			long time = System.currentTimeMillis();
			if(child==null) {
				child = new LambkitChildNode();
				child.setId(node.getId());
				child.setApplicationName(node.getApplicationName());
				child.setKey(node.getKey());
				child.setParentNodeUrl(node.getParentNodeUrl());
				child.setUrl(node.getUrl());
				child.setLinkType(node.getLinkType());
				child.setType(node.getType());
				child.setStartTime(time);
				child.setCommitTime(time);
			} else {
				child.setCommitTime(time);
			}
			childNodes.put(node.getId(), child);
//			Lambkit.getCache().put(LambkitNodeManager.cacheName, "other_node_" + node.getId(), node, 120);
//			Lambkit.getCache().put(LambkitNodeManager.cacheName, "other_node_kes", childNodes.keySet());
			return child;
		}
		return null;
	}

	public LambkitNode getNode() {
		return node;
	}

	public void setNode(LambkitNode node) {
		this.node = node;
	}

	public LambkitParentNode getParentNode() {
		return parentNode;
	}

	public void setParentNodeP2c(LambkitNodeP2c nodeP2c) {
		this.parentNode = new LambkitParentNode(nodeP2c);
		this.node.setLevel(parentNode.getLevel() + 1);
	}
	public void setParentNode(LambkitParentNode parentNode) {
		this.parentNode = parentNode;
	}

	public LambkitSiblingNode getSiblingNode() {
		return siblingNode;
	}

	public void setSiblingNodeS2p(LambkitNodeS2p siblingNode) {
		this.siblingNode = new LambkitSiblingNode(siblingNode);
		NetUrl url = siblingNode.getUrl();
		if(url!=null) {
			this.siblingNode.setSiblingUrl(url.url());
		}
	}

	public void setSiblingNode(LambkitSiblingNode siblingNode) {
		this.siblingNode = siblingNode;
	}

	public Map<String, LambkitChildNode> getChildNodes() {
		return childNodes;
	}
	
	public void setChildNodes(Map<String, LambkitChildNode> childNodes) {
		this.childNodes = childNodes;
	}

	public LambkitNodeService getService() {
		return service;
	}

	public void setService(LambkitNodeService service) {
		this.service = service;
	}


}
